package com.lzy.cloud.payment.pay.weixin;

import com.lzy.cloud.payment.constants.CommonConstants;
import org.jdom2.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * @ClassName: WxPayApi
 * @Description:微信请求公共类
 * @author: stone
 * @date: 2017年5月17日 下午2:06:27
 * @Copyright: 2017 www.tydic.com Inc. All rights reserved.
 */
public class WxPayApi {
    static Logger logger = LoggerFactory.getLogger(WxPayApi.class);

    /**
     * 统一微信调用公共方法
     *
     * @param data       请求参数
     * @param url        请求地址
     * @param targetType 目标类型
     * @return
     */
    public static WxPayData requestWXApi(WxPayData data, String url, Integer targetType) {
        data.put("nonce_str", WxPayUtil.GenerateNonceStr(8));//随机字符串
        data.put("sign", data.makeSign());

        String xml = data.toXml();
        String response = null;
        //统一下单、查询订单、退款查询 用Http请求
        //申请退款用	Https请求
        if (url.equals(Config.REFUND_URL)) {
            response = WxPayUtil.sendHttps(url, "POST", xml, targetType, getMCHID(targetType));
        } else {
            response = WxPayUtil.sendHttp(url, "POST", xml);
        }
        WxPayData result = new WxPayData();
        try {
            result.putAll(WxPayUtil.toMap(response));
        } catch (JDOMException | IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String txt2String(File file) {
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法，一次读一行
                result.append(System.lineSeparator() + s);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    /**
     * 根据不同类型
     *
     * @param targetType
     * @return
     */
    public static WxPayData getWxPayData(Integer targetType) {
        WxPayData data = new WxPayData();
        if (CommonConstants.PayTargetType.APP.getIndex() == targetType) {
            data.put("appid", Config.APPID);
            data.put("mch_id", Config.MCHID);
            data.put("op_user_id", Config.MCHID);
        } else {
            data.put("appid", Config.WEB_APPID);
            data.put("mch_id", Config.WEB_MCHID);
            data.put("op_user_id", Config.WEB_MCHID);
        }
        return data;
    }

    /**
     * 微信返回参数(APP)
     *
     * @param result
     * @param dt
     * @return
     */
    public static WxPayData getAppResponseData(WxPayData result, Date dt) {
        WxPayData resultParams = new WxPayData();
        resultParams.put("appid", result.get("appid"));
        resultParams.put("noncestr", result.get("nonce_str"));
        resultParams.put("package", "Sign=WXPay");
        resultParams.put("partnerid", result.get("mch_id"));
        resultParams.put("timestamp", dt.getTime() / 1000);
        resultParams.put("prepayid", result.get("prepay_id"));
        resultParams.put("sign", resultParams.makeSign());
        //扫码支付
        if (com.lzy.framework.core.utils.StringUtil.trimToNull(result.get("code_url") + "") != null && !result.get("code_url").equals("null")) {
            WxPayData scanCodeParams = new WxPayData();
            scanCodeParams.put("code_url", result.get("code_url") + "");
            return scanCodeParams;
            //APP支付
        } else {
            return resultParams;
        }
    }

    /**
     * 微信返回参数(WEB,小程序)
     *
     * @param result
     * @param dt
     * @return
     */
    public static WxPayData getWebResponseData(WxPayData result, Date dt) {
        WxPayData resultParams = new WxPayData();
        resultParams.put("appId", String.valueOf(result.get("appid")));
        resultParams.put("nonceStr", String.valueOf(result.get("nonce_str")));
        resultParams.put("package", "prepay_id=" + result.get("prepay_id"));
        resultParams.put("timeStamp", String.valueOf(dt.getTime() / 1000));
        resultParams.put("signType", "MD5");
        resultParams.put("paySign", resultParams.makeSign());
        resultParams.put("packages", "prepay_id=" + result.get("prepay_id"));
        return resultParams;
    }

    /**
     * 获取商户ID
     *
     * @param targetType
     * @return
     */
    public static String getMCHID(Integer targetType) {
        switch (targetType) {
            case 0:
                return Config.MCHID;
            case 1:
                return Config.WEB_MCHID;
        }
        return null;
    }

    public static void main(String[] args) {

        //微信退款

      /*  WxPayData data = new WxPayData();
        data.put("appid","wxf8b1ff5bd8bd76e8");
        data.put("mch_id", "1422034802");
        data.put("op_user_id", "1422034802");
        data.put("out_trade_no", "2110114141009595");   //商户订单号
        data.put("out_refund_no", "2110114141009590");  //商户退款单号
        data.put("total_fee", "1");  //订单总额
        data.put("refund_fee", "1");  //退款金额
        data.put("nonce_str", WxPayUtil.GenerateNonceStr(8));//随机字符串
        data.put("sign", data.makeSign());
        String response = WxPayUtil.sendHttps("https://api.mch.weixin.qq.com/secapi/pay/refund", "POST", data.toXml(), 1);
        System.out.println(response);*/


        /*Integer i = null;
        System.out.println(1 == i);*/
        /*WxPayData wp = new WxPayData();
        wp.put("return_code", "SUCCESS");
		wp.put("result_code", "SUCCESS");
		wp.put("openid", "ofQO5wHkQUCVhSFKh0mdnvNcrJI4");
		wp.put("trade_type", "APP");
		wp.put("bank_type", "CFT");
		wp.put("fee_type", "CNY");
		wp.put("total_fee", "1");
		wp.put("cash_fee", "1");
		wp.put("transaction_id", "4008462001201706023896095084");
		wp.put("out_trade_no", "12177662378246144");
		wp.put("time_end", "20170602161617");
		wp.put("appid", Config.APPID);
        wp.put("mch_id", Config.MCHID);
		wp.put("nonce_str", "NWJPNPQA");//随机字符串
		wp.put("sign", "85B6299BF5B6AC023302B9C7897C235D");
		wp.put("is_subscribe", "N");
		testPost(wp.toXml()); */

		/*try {
            System.out.println("私钥:"+FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY));
			System.out.println("支付宝公钥:"+FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY));

			AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),AlipayConfig.FORMAT,AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
			AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();

			//全部退款   成功
			request.setBizContent("{" +
					"\"out_trade_no\":\"2081116731000387\"," +
					"\"refund_amount\":9.3" +
					"}");

			//部分退款  成功
			request.setBizContent("{" +
					"\"out_trade_no\":\"2071910241009153\"," +
					"\"out_request_no\":\"888\"," +
					"\"refund_amount\":0.30" +
					"}");
			AlipayTradeRefundResponse response;
			response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("调用成功");
			} else {
				System.out.println("调用失败");
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}*/

		/*Map<String,String> data = new HashMap<String,String>();
		data.put("app_id", AlipayConfig.APPID);             //支付宝分配的商户号
		data.put("method", "alipay.trade.app.pay");         //接口名称
		data.put("charset", AlipayConfig.CHARSET);          //请求编码
		data.put("sign_type", AlipayConfig.SIGNTYPE);       //签名方式
		data.put("timestamp", "2017-05-25 15:57:30"); //请求时间
		data.put("version", "1.0");                         //支付宝版本
		data.put("notify_url", AlipayConfig.NOTIFY_URL);    //异步回调地址

		try {
			Map<String,String> map = new HashMap<String,String>();
			map.put("subject", "test");
			map.put("out_trade_no", "405241019197497");
			map.put("total_amount", "0.01");
			map.put("product_code", CommonConstants.PRODUCT_CODE);
			map.put("timeout_express", "30m"); //设置订单失效时间 30分钟

			String biz_content = net.sf.json.JSONObject.fromObject(sortMapByKey(map)).toString();
			data.put("biz_content",biz_content);

			logger.info("------支付宝未签名数据--------data="+data.toString());
			String content = AlipaySignature.getSignCheckContentV2(data);   //待签名的内容
			logger.info("-----------待验签数据-----------content="+content);
			String sign = AlipaySignature.rsaSign(content, new FileUtil().getResources(AlipayConfig.RSA_PRIVATE_KEY), AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);  //签名结果
			data.put("sign", sign);
			logger.info("------支付宝签名成功------"+data.toString());
		} catch (AlipayApiException e) {
			logger.error("----支付宝签名异常------");
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}*/

		/*AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),AlipayConfig.FORMAT,AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
		AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
		request.setBizContent("{" +
		"\"subject\":\"test\"," +
		"\"out_trade_no\":\"405241019197497\"," +
		"\"total_amount\":0.01," +
		"\"buyer_id\":2088221282730032" +
		"  }");
		AlipayTradeCreateResponse response;
		try {
			response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("调用成功");
			} else {
				System.out.println("调用失败");
			}
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/


		/*AlipayClient alipayClient = new DefaultAlipayClient(
				"https://openapi.alipay.com/gateway.do",
				AlipayConfig.APPID,
				FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),
				AlipayConfig.FORMAT,
				AlipayConfig.CHARSET,
				FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),
				AlipayConfig.SIGNTYPE);

		AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
		request.setApiVersion("1.0");
		request.setNotifyUrl("http://www.baidu.com");
		request.setBizContent("{\"timeout_express\":\"30m\",\"seller_id\":\"\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"0.01\",\"subject\":\"1\",\"body\":\"我是测试数据\",\"out_trade_no\":\"46546546546546546542132\"}");
//		request.setBizContent("{" +
//		"\"subject\":\"test\"," +
//		"\"out_trade_no\":\"405241019197497\"," +
//		"\"total_amount\":0.01," +
//		"\"product_code\":QUICK_MSECURITY_PAY" +
//		"  }");
		AlipayTradeCreateResponse response;
		try {
			response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("调用成功");
			} else {
				System.out.println("调用失败");
			}
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/

		/*AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),AlipayConfig.FORMAT,AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的m odel入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setSubject("test");
		model.setBody("test");
		model.setOutTradeNo("3090513281001848");
		model.setTimeoutExpress("90m");
		model.setTotalAmount("6");
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		request.setNotifyUrl(AlipayConfig.NOTIFY_URL);
		try {
		        //这里和普通的接口调用不同，使用的是sdkExecute
		        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
		        System.out.println("-------"+response.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
		    } catch (AlipayApiException e) {
		        e.printStackTrace();
		}*/
		/*try {
			AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),AlipayConfig.FORMAT,AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
			AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
			request.setBizContent("{" +
					"\"out_trade_no\":\"405241019197497\"," +
					"  }");
			AlipayTradeQueryResponse response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("调用成功");
			} else {
				System.out.println("调用失败");
			}
		} catch (Exception e) {
			// TODO: handle exception
		}*/


		/*WxPayData data = new WxPayData();
        data.put("app_id", AlipayConfig.APPID);           //支付宝分配的商户号
        data.put("method", CommonConstants.METHOD_QUERY); //接口名称
        data.put("charset", AlipayConfig.CHARSET);        //请求编码
        data.put("sign_type", AlipayConfig.SIGNTYPE);     //签名方式
        data.put("timestamp", UtilDate.getDateFormatter()); //请求时间
		data.put("version", "1.0");
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),data.toJson(),AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
		AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
		AlipayTradeRefundModel model = new AlipayTradeRefundModel();
		model.setOutTradeNo("3090513281001848");
		model.setOutRequestNo("110");
		request.setBizModel(model);
		AlipayTradeFastpayRefundQueryResponse response;
		try {
			response = alipayClient.execute(request);
			//logger.info("---支付宝返回退款查询结果---"+response.getBody());
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}*/
       /* WxPayData data = new WxPayData();
        data.put("app_id", AlipayConfig.APPID);           //支付宝分配的商户号
        data.put("method", CommonConstants.METHOD_QUERY); //接口名称
        data.put("charset", AlipayConfig.CHARSET);        //请求编码
        data.put("sign_type", AlipayConfig.SIGNTYPE);     //签名方式
        data.put("timestamp", UtilDate.getDateFormatter()); //请求时间
        data.put("version", "1.0");
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),data.toJson(),AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
		AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
		//全额
		request.setBizContent("{" +
				"\"out_trade_no\":\"3090511141001849\"," +
				"\"out_request_no\":\"2071910241009156\"" +
				"  }");*/

        //部分退款  -成功
		/*request.setBizContent("{" +
		"\"out_trade_no\":\"2071910241009153\"," +
		"\"out_request_no\":\"888\"" +
		"  }");*/
		/*AlipayTradeFastpayRefundQueryResponse response;
		try {
			response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("调用成功");
				logger.info("---支付宝返回退款查询结果---"+response.getBody());
			} else {
				System.out.println("调用失败");
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}*/


        //微信申请退款
       /* WxPayData data = new WxPayData();
        data.put("appid", Config.APPID);
        data.put("mch_id", Config.MCHID);
        data.put("out_trade_no", "3090513281001848");   //商户订单号
        data.put("out_refund_no", "3081416441007591");  //商户退款单号
        data.put("total_fee",  "600");  //订单总额
        data.put("refund_fee",  "600");  //退款金额
        data.put("op_user_id", Config.MCHID);  //操作员帐号
        System.out.println(data.toJson());
        WxPayData result = WxPayApi.requestWXApi(data,Config.REFUND_URL),
                resultParams = new WxPayData();
        logger.info("微信支付发起");
        logger.info("请求数据：" + data.toJson());
        logger.info("返回数据："+result.toJson());
		/*WxPayData data = new WxPayData();
        data.put("out_trade_no", "2071810401007539");   //本地订单号
        WxPayData result = WxPayApi.requestWXApi(data,Config.REFUND_QUERY_URL),
        					resultParams = new WxPayData();
        logger.info("微信支付发起");
        logger.info("请求数据：" + data.toJson());
        logger.info("返回数据："+result.toJson());*/


        //扫码支付
		/*WxPayData data = new WxPayData();
		Date dt = new Date();
        data.put("time_start", StringUtil.dateFormat(dt, "yyyyMMddHHmmss"));//交易起始时间
        dt.setTime(dt.getTime() + (1800 * 1000));
        data.put("time_expire", StringUtil.dateFormat(dt, "yyyyMMddHHmmss"));//交易结束时间
        //data.put("goods_tag", "lzhy20160505");//商品标记
        data.put("trade_type", "NATIVE");                             //交易类型
        String outTradeNo = "2017080217" +(int)(Math.random() * 100);
        data.put("out_trade_no", outTradeNo);       //本地订单号
        data.put("body", "test");                   //商品名称
        data.put("total_fee", "1");  //交易金额
        data.put("notify_url", Config.NOTIFY_URL);   //异步回调地址
        data.put("spbill_create_ip", Config.IP);     //用户发起请求IP地址
        data.put("appid", Config.WEB_APPID);
        data.put("mch_id", Config.MCHID);

        WxPayData result = WxPayApi.requestWXApi(data,Config.UNIFIEDORDER_URL),
        		resultParams = new WxPayData();

        logger.info("微信支付发起");
        logger.info("请求数据：" + data.toJson());
        logger.info("返回数据："+result.toJson());
        if (result.get(CommonConstants.RETURN_CODE).equals(CommonConstants.SUCCESS) && result.get(CommonConstants.RESULT_CODE).equals(CommonConstants.SUCCESS)){

        	resultParams.put("code_url", result.get("code_url"));
            logger.info("返回提交数据---："+resultParams.toJson());
        }else{
           Ensure.that(true).isFalse("09000009");  //微信统一下单异常
           logger.info("统一下单异常");
        }*/


		/*AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AlipayConfig.APPID,FileUtil.readString(AlipayConfig.RSA_PRIVATE_KEY),AlipayConfig.FORMAT,AlipayConfig.CHARSET,FileUtil.readString(AlipayConfig.ALIPAY_PUBLIC_KEY),AlipayConfig.SIGNTYPE);
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		request.setBizContent("{" +
		"\"out_trade_no\":\"4082315321003512\"" +
		"  }");
		AlipayTradeQueryResponse response ;
		try {
			response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("调用成功");
				System.out.println("---支付宝订单查询结果---"+response.getBody());
			} else {
				System.out.println("调用失败");
			}
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/

        //微信订单查询
		/*WxPayData data = new WxPayData();
		data.put("appid", Config.APPID);
		data.put("mch_id", Config.MCHID);
        data.put("out_trade_no", "6082512971007637");   //商户订单号
        System.out.println(data.toJson());
        WxPayData result = WxPayApi.requestWXApi(data,"https://api.mch.weixin.qq.com/pay/orderquery");
        System.out.println("微信支付发起");
        System.out.println("请求数据：" + data.toJson());
        System.out.println("返回数据："+result.toJson());*/


    }

    public static void testPost(String urlStr) {
        try {

            String xmlInfo = urlStr;
            SimpleDateFormat format = new SimpleDateFormat(
                    "yyyy-MM-dd hh:mm:ss");
            System.out.println(format.format(new Date()) + "---发送信息开始。");

            System.out.println("xmlInfo=" + xmlInfo);

            URL url = new URL("http://192.168.89.21:8080//api/pay/wxAsyNotify");
            URLConnection conn = url.openConnection();
            conn.setRequestProperty("Pragma:", "no-cache");
            conn.setRequestProperty("Cache-Control", "no-cache");
            conn.setRequestProperty("Content-Type", "application/xml"); //如果是json数据 把xml 改为json
            conn.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(
                    conn.getOutputStream());
            out.write(new String(xmlInfo.getBytes("utf-8")));
            out.flush();
            out.close();

            BufferedReader read = new BufferedReader(new InputStreamReader(
                    conn.getInputStream()));
            String str = read.readLine();
            read.close();
            // ReceiveWeixinMsg recemsg = (ReceiveWeixinMsg) new
            // ParseXmlUtil().parseXmlFromObj(ReceiveWeixinMsg.class,
            // conn.getInputStream(), "xml", null);
            // System.out.println("接受信息为："+recemsg.getContent());
            System.out.println(format.format(new Date()) + "---接受结束。");
            System.out.println("-------结果-----" + str);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用 Map按key进行排序
     *
     * @param map
     * @return
     */
    public static Map<String, String> sortMapByKey(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap<String, String>(new MapKeyComparator());
        sortMap.putAll(map);
        return sortMap;
    }
}

class MapKeyComparator implements Comparator<String> {
    public int compare(String str1, String str2) {
        return str1.compareTo(str2);
    }
}
